/*
** $身份: 嘞协程库.c $
** 协程 库
** 参见 炉啊.h 版权声明
*
*
* 本人所用声母表: a啊 b哔 c西 d迪 e鹅 f弗 g哥 
* h喝 i艾 j鸡 k颗 l嘞 m摸 n恩
* o欧 p匹 q气 r日 s丝 t嚏 
* u由 v微 w屋 x斯 y医 z只
*
* 一些英文单词缩写,我的翻译大多来自;有道词典,谷歌翻译,百度.
* 一些术语实在不好翻译,所以就原封不动.
* 
* 一些特有的表示特有库的术语是无法翻译的 *
* 否则编译器不能识别不能通过,第一版汉化就行不通.
* 
*/

#define 嘞协程库_西
#define 炉啊_库

#include "嘞前缀.h"

#include <stdlib.h>

#include "炉啊.h"

#include "嘞辅库.h"
#include "炉啊库.h"

static 炉啊_国 *取西欧 (炉啊_国 *嘞) {
  炉啊_国 *西欧 = 炉啊_到线程(嘞, 1);
  炉啊嘞_实参预期(嘞, 西欧, 1, "线程");
  return 西欧;
}

/*
** 恢复一个协程. 返回非错误结果的号码情况 或 -1表示错误.
*/

static int 辅恢复 (炉啊_国 *嘞, 炉啊_国 *西欧, int 恩实参) {
  int 状态, 恩恢复;
  if (!炉啊_检查栈(西欧, 恩实参)) {
    炉啊_推字面(嘞, "太多实参到恢复");
    return -1;  /* 错误旗 */
  }
  炉啊_斯移动(嘞, 西欧, 恩实参);
  状态 = 炉啊_恢复(西欧, 嘞, 恩实参, &恩恢复);
  if (状态 == 炉啊_可以 || 状态 == 炉啊_产出) {
    if (!炉啊_检查栈(嘞, 恩恢复 + 1)) {
      炉啊_弹(西欧, 恩恢复);  /* 移除结果无论如何 */
      炉啊_推字面(嘞, "太多结果到恢复");
      return -1;  /* 错误旗 */
    }
    炉啊_斯移动(西欧, 嘞, 恩恢复);  /* 移动已产出值 */
    return 恩恢复;
  }
  else {
    炉啊_斯移动(西欧, 嘞, 1);  /* 移动错误消息 */
    return -1;  /* 错误旗 */
  }
}

static int 炉啊哔_西欧恢复 (炉啊_国 *嘞) {
  炉啊_国 *西欧 = 取西欧(嘞);
  int 日;
  日 = 辅恢复(嘞, 西欧, 炉啊_取顶部(嘞) - 1);
  if (日 < 0) {
    炉啊_推布尔(嘞, 0);
    炉啊_插入(嘞, -2);
    return 2;  /* 返回假 + 错误消息 */
  }
  else {
    炉啊_推布尔(嘞, 1);
    炉啊_插入(嘞, -(日 + 1));
    return 日 + 1;  /* 返回真 + '恢复' 返回的 */
  }
}

static int 炉啊哔_辅缠绕 (炉啊_国 *嘞) {
  炉啊_国 *西欧 = 炉啊_到线程(嘞, 炉啊_上值索引(1));
  int 日 = 辅恢复(嘞, 西欧, 炉啊_取顶部(嘞));
  if (日 < 0) {
    int 静 = 炉啊_状态(西欧);
    if (静 != 炉啊_可以 && 静 != 炉啊_产出)
      炉啊_重新设置线程(西欧);  /* 在错误的情况下关闭变量 */
    if (炉啊_类型(嘞, -1) == 炉啊_嚏串) {  /* 错误对象是一个串? */
      炉啊嘞_哪里(嘞, 1);  /* 添加额外信息, 如果可用 */
      炉啊_插入(嘞, -2);
      炉啊_连结(嘞, 2);
    }
    return 炉啊_错误(嘞);  /* 传播错误 */
  }
  return 日;
}

static int 炉啊哔_西欧创建 (炉啊_国 *嘞) {
  炉啊_国 *恩嘞;
  炉啊嘞_检查类型(嘞, 1, 炉啊_嚏函数);
  恩嘞 = 炉啊_新线程(嘞);
  炉啊_推值(嘞, 1);  /* 移动函数到顶部 */
  炉啊_斯移动(嘞, 恩嘞, 1);  /* 移动函数从 嘞 到 恩嘞 */
  return 1;
}


static int 炉啊哔_西欧缠绕 (炉啊_国 *嘞) {
  炉啊哔_西欧创建(嘞);
  炉啊_推西闭包(嘞, 炉啊哔_辅缠绕, 1);
  return 1;
}


static int 炉啊哔_产出 (炉啊_国 *嘞) {
  return 炉啊_产出(嘞, 炉啊_取顶部(嘞));
}

#define 西欧丝_跑		0
#define 西欧丝_死	    1
#define 西欧丝_产出	    2
#define 西欧丝_规范	    3

static const char *const 状态名[] =
  {"正在跑", "死", "暂停", "正常"};


static int 辅状态 (炉啊_国 *嘞, 炉啊_国 *西欧) {
  if (嘞 == 西欧) return 西欧丝_跑;
  else {
    switch (炉啊_状态(西欧)) {
      case 炉啊_产出:
        return 西欧丝_产出;
      case 炉啊_可以: {
        炉啊_调试 啊日;
        if (炉啊_取栈(西欧, 0, &啊日))  /* 它有框架吗? */
          return 西欧丝_规范;  /* 它正在跑 */
        else if (炉啊_取顶部(西欧) == 0)
            return 西欧丝_死;
        else
          return 西欧丝_产出;  /* 初始状态 */
      }
      default:  /* 一些错误发生 */
        return 西欧丝_死;
    }
  }
}


static int 炉啊哔_西欧状态 (炉啊_国 *嘞) {
  炉啊_国 *西欧 = 取西欧(嘞);
  炉啊_推串(嘞, 状态名[辅状态(嘞, 西欧)]);
  return 1;
}


static int 炉啊哔_可产出的 (炉啊_国 *嘞) {
  炉啊_国 *西欧 = 炉啊_是否无(嘞, 1) ? 嘞 : 取西欧(嘞);
  炉啊_推布尔(嘞, 炉啊_是否可产出的(西欧));
  return 1;
}


static int 炉啊哔_西欧正在跑 (炉啊_国 *嘞) {
  int 是否主要 = 炉啊_推线程(嘞);
  炉啊_推布尔(嘞, 是否主要);
  return 2;
}

static int 炉啊哔_关闭 (炉啊_国 *嘞) {
  炉啊_国 *西欧 = 取西欧(嘞);
  int 状态 = 辅状态(嘞, 西欧);
  switch (状态) {
    case 西欧丝_死: case 西欧丝_产出: {
      状态 = 炉啊_重置线程(西欧);
      if (状态 == 炉啊_可以) {
        炉啊_推布尔(嘞, 1);
        return 1;
      }
      else {
        炉啊_推布尔(嘞, 0);
        炉啊_斯移动(西欧, 嘞, 1);  /* 复制错误消息 */
        return 2;
      }
    }
    default:  /* 正常或正在跑的协程 */
      return 炉啊嘞_错误(嘞, "不能关闭一个 %s 协程", 状态名[状态]);
  }
}

static const 炉啊嘞_寄存 西欧_函丝[] = {
  {"创建", 炉啊哔_西欧创建},
  {"恢复", 炉啊哔_西欧恢复},
  {"正在跑", 炉啊哔_西欧正在跑},
  {"状态", 炉啊哔_西欧状态},
  {"纠缠", 炉啊哔_西欧纠缠},
  {"产出", 炉啊哔_产出},
  {"是否可产出的", 炉啊哔_可产出的},
  {"关闭", 炉啊哔_关闭},
  {NULL, NULL}
};



炉啊模_应用程序接口 int 炉啊打开_协程 (炉啊_国 *嘞) {
  炉啊嘞_新库(嘞, 西欧_函丝);
  return 1;
}